/** \file    qconvert.cpp
  * \brief   Converts between different image in-memory representations (QT-specific).
  * \date    2001
  * \author  Fedor Chelnokov
  * \version $Header: /home/cscom1r4/cvsroot/cs/imglib/src/qconvert.cpp,v 1.1 2004/02/04 14:43:23 cscom1r4 Exp $
  */

//#if !(defined _MSC_VER && _MSC_VER>=1300) //Qt library is comatible with compiler

#include <qimage.h> //if you have not Qt then make empty file to prevent errors
#ifdef QIMAGE_H //Qt library realy presents

#include "imglib/convert.h"
#include "imglib/bitmap.h"
#include "imglib/Arr2Dimg.h"
#include "imglib/imageclass.h"
#include "cinline.h"

namespace img {

void shareQdata( AImage &aimg, const QImage &qimg )
{
	assert(qimg.depth() == 32);
	aimg.ShareData( reinterpret_cast<bRGB*>(qimg.bits()), qimg.width(), qimg.height() );
}

void shareQdata( byte_image &aimg, const QImage &qimg )
{
	assert(qimg.depth() == 32);
	aimg.attach(qimg.bits(), qimg.width(), qimg.height());
	assert(aimg.bytes() == qimg.numBytes());
}

void shareQdata( bitmap &bmp, const QImage &qimg )
{
	assert(qimg.depth() == 1);
	size_t alignment;
	size_t net_scansize = (qimg.width()+7)/8;
	if (net_scansize == qimg.bytesPerLine())
		alignment = 0;
	else
		for (alignment = 2; ; alignment *= 2) 
			if (qimg.bytesPerLine() == ((net_scansize + alignment - 1) / alignment) * alignment)
				break;
	bmp.attach(qimg.bits(), qimg.width(), qimg.height(), alignment);
	assert(bmp.scansize() == qimg.bytesPerLine() && bmp.bytes() == qimg.numBytes());
}

QImage bmpImage( bitmap &bmp )
{
	//!!! Qt has bug in the case when scansize is not 32-bit divisible
	QImage res( (uchar*)bmp.data(), bmp.width(), bmp.height(), 1, 0, 2, QImage::BigEndian );
	res.setColor( 0, qRgb(0,0,0) );
	res.setColor( 1, qRgb(255,255,255) );
	return res;
}

QImage qimg(const byte_image &img)
{
	QImage res((uchar*)img.data(), (int)img.width(), (int)img.height(), 32, 0, 0, QImage::IgnoreEndian);
	assert(res.numBytes() == img.bytes());
	if (img.order() == bottom_up)
		return res.mirror();
	else
		return res;
}

template <> void copy(bitmap & dest, const QImage & source)
{
	QImage q(trueColor(source));
	byte_image bimg;
	shareQdata(bimg, q);
	copy(dest, bimg);
}

template <> void copy(AImage & dest, const QImage & source)
{
	AImage a;
	shareQdata(a, trueColor(source));
	dest = a;
}

template <> void copy(QImage & dest, const FImage & source)
{
	assert( source.Width() == dest.width() && source.Height() == dest.height() );
	AImage aimg;
	shareQdata( aimg, dest );
	copy(aimg, source);
}

template <> void copy(FImage & dest, const QImage & source)
{
	if( source.depth() != 32 ) {
		QImage dup( source.convertDepth(32) );
		AImage aimg;
		shareQdata( aimg, dup );
		copy(dest, aimg);
	} else {
		AImage aimg;
		shareQdata( aimg, source );
		copy(dest, aimg);
	}
}

template <> void copy(QImage & dest, const byte_image & source)
{
	dest = qimg(const_cast<byte_image &>(source)).copy();
}

QImage trueColor( const QImage &source )
{
	return (source.depth()==32) ? source : source.convertDepth(32);
}

} //namespace img

#endif //QIMAGE_H

//#endif //!MSC_VER>=1300
